# -*- coding: utf-8 -*-
"""
间隔调度，比对计算指标，提示买入或卖出
"""
import pandas as pd
import sys
import time
from WindPy import *


# 添加自定义模块
from stock_py.config import config as conf
from stock_py.tools.database import stock_db as mydb
from stock_py.tools.tools_py.gui_py import gui_show as gui

# 作为全局变量，启动wind接口
w.start()
    
# 指定股票代码的文件
specified_code_file=conf.get_specified_code()
# 存放指定股票ema，coe等数据的文件
specified_code_ema=conf.get_specified_code_ema()
# 存放指定股票实时数据的文件
specified_code_timely_data=conf.get_specified_code_timely_data()
# 买卖提示的log备忘文件
buy_info_log = conf.get_buy_info_log()

# 读取指定的股票代码
def read_specified_code():
    '''读取指定的股票代码'''
    df1 = pd.read_excel(specified_code_file,sheetname='砝码3因子的')
    df2 = pd.read_excel(specified_code_file,sheetname='我关注的')
    df = pd.concat([df1,df2])
    df.columns = [col.lower() for col in df.columns]  # 列名转小写
    # 去重后返回股票代码
    df = df.drop_duplicates('code')
    del df['buy']
    return df

# 读取指定代码的ema，coe等数据，写入文件，方便全局读取
def read_all_ema_from_db(conn,codes):
    '''读取所有指定股票的ema，coe等数据，写入文件，方便全局读取。codes是list格式，就算是只有一个元素'''
    # 读取最近的日期
    sql = " select max(dates from stock_qx "
    dates = pd.read_sql(sql,conn).ix[0,0]
    # 读取所有指定的股票数据
    all_data=pd.DataFrame()
    for code in codes:
        sql = r"""select code,name,dates,qema_15,qema_25,qcoe_15,qcoe_25 
            from stock_ema where code='limit_code' and dates='limit_date' """
        sql = sql.replace('limit_code',code)
        sql = sql.replace('limit_date',dates)
        df=pd.read_sql(sql,conn)
        all_data = pd.concat([all_data,df])
    all_data.columns = [col.lower() for col in all_data.columns]
    # 写入到文件
    csv_file=specified_code_ema
    all_data.to_csv(csv_file,index=False,encoding='utf8',float_format='%.4f')

# 读取指定股票的wind实时数据
def read_timely_data(codes):
    '''针对所有指定股票的code，读取wind接口的实时数据。并且写到文件'''
    all_data=[]
    fields="rt_last"
    for code in codes:
        code2 = code[2:]+"."+code[:2].upper()  # 将股票代码转成wind要求的格式
        data = w.wsq(code2,fields)  # 实时价格数据
        price = [code, data.Data[0][0]]  # 将code和price组成一个列表
        all_data.append(price)
    # 转成数据框,写到文件
    all_data2 = pd.DataFrame(all_data,columns=['code','price'])
    csv_file=specified_code_timely_data
    all_data2.to_csv(csv_file,index=False,encoding='utf8',float_format='%.4f')

def code_buy():
    '''返回哪些股票已经购买了，否则无法判断是否提示买入还是卖出。
    一般买入的也就是几只，所以使用list格式返回'''
    df2 = pd.read_excel(specified_code_file,sheetname='我关注的')
    codes = df2[df2['buy']==1]['code']
    return list(codes)

def is_buy_or_sale(code,qema_15,qema_25,now_price,buy=[]):
    '''判断是应该买入还是卖出
    ema15,ema25是计算的指标，now_price是实时价格，buy是指哪些股票是否已经买入
    '''
    sp=""
    # 如果没有购买，但是满足购买条件，就提示买入
    if code not in buy:
        if now_price > qema_15:  # 满足买入条件
            sp=sp+code+" 大于持有线(15),满足购入要求..."
        if now_price > qema_25:
            sp=sp+"大于生命线(25),可能有中期行情..."
        return sp
    # 如果已经购买，满足卖出条件，就提示卖出
    if code in buy:
        if now_price < qema_15:  # 满足卖出条件
            sp=sp+code+" 低于持有线(15),请及时卖出..."
            return sp
    # 如果两者都没有满足，就返回None
    return ''
    
    
# 对比wind的实时数据和ema，coe等指标计算结果
def cmp_eam_and_timely_data():
    # 读取指标结果和实时数据
    ema = pd.read_csv(specified_code_ema,encoding='utf8')
    ema.index=ema.code
    timely = pd.read_csv(specified_code_timely_data,encoding='utf8')
    timely.index=timely.code
    # 读取哪些股票是否已经购买的
    has_buy = code_buy()
    # 比较两个文件code是否一致
    set_ema = set(ema.code)
    set_timely = set(timely.code)
    diff = set_ema-set_timely
    if len(diff)>0:
        print('ema中有而实时数据中没有的是：%s，请核查...' %diff)
    # 买卖的判断作为一个series返回
    all_buy_info = []
    # 通过循环计算比较
    all_code=ema['code']
    for code in all_code:
        qema_15 = ema.ix[code,'qema_15']
        qema_25 = ema.ix[code,'qema_25']
        now_price = timely.ix[code,'price']
        # 判断是应该买入还是卖出
        buy_tips=is_buy_or_sale(code,qema_15,qema_25,now_price,has_buy)
        # 如果有提示信息，就放到series中
        if buy_tips:
            all_buy_info.append([code,buy_tips])
    # 转成df后返回
    return pd.DataFrame(all_buy_info, columns=['code','tips'])

def buy_info_to_log(file,buy_series):
    '''将股票买卖提示信息写到log文件备忘'''
    # 如果是字符串类型，使用writelines
    if type(buy_series)==str:
        with open(file,'a',encoding='utf8') as f:
            f.writelines(buy_series+'\n')
    else:
        buy_series.to_csv(file,mode='a',encoding='utf8')

def main(logger=''):
    # 导入日志
    logger = conf.get_log()
    logger.info('---------------------------------------')
    # 连接数据库
    conn = mysql.connect()
    logger.info('启动wind接口，连接数据库成功...')
    #----------------------------------------------------
    # 读取需要判断的股票代码
    code_df = read_specified_code()  # 包含code，name的df
    all_code = list(code_df.code)
    # 从数据库读取ema数据，写入数据文件 specified_code_ema
    # 如果这个文件是已经计算好的，其实是不用再计算这一步
    read_all_ema_from_db(conn,codes=all_code)
    # 从wind接口读取实时数据，写入specified_code_timely_data
    read_timely_data(codes=all_code)
    # 判断哪些股票应该买还是卖
    all_buy_tips=cmp_eam_and_timely_data()
    # 将code的name拼接上去
    all_buy_tips = pd.merge(all_buy_tips, all_code, on='code')
    #----------------------------------------------------
    # 将判断结果写入文件
    buy_info_to_log(buy_info_log,'--------------------------------')  # 写入分割线
    all_buy_tips.to_csv(buy_info_log,mode='a')
    # 弹出窗口
    if len(all_buy_tips)>0:
        gui.show_message(all_buy_tips)
    # 关闭数据库连接，关闭日志句柄
    conn.close()
    logging.shutdown()
    
if __name__ == '__main__':
    while True:
        main()
        time.sleep(60)  # 睡眠60秒
        time.sleep(60)  # 睡眠60秒
        time.sleep(60)  # 睡眠60秒
        time.sleep(60)  # 睡眠60秒
    